package com.lzyjkz.quick_components.service;

import com.lzyjkz.quick_components.constant.RedisBucketConstant;
import com.lzyjkz.quick_components.exceptions.LoginExpiredException;
import com.lzyjkz.quick_components.utils.JwtUtil;
import com.lzyjkz.quick_components.utils.RedisCache;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public final class TokenService {

    private final RedisCache redisCache;
    private final JwtUtil jwtUtil;

    public String createUserToken(UserDetails userDetails){
        Map<String, Object> claims = new HashMap<>();
        String uuid = UUID.randomUUID().toString();
        claims.put("uuid", uuid);
        redisCache.setCacheObject(RedisBucketConstant.LOGIN_TOKEN_BUCKET + uuid, userDetails, 30, TimeUnit.HOURS);
        return jwtUtil.createJwtToken(claims);
    }

    public UserDetails getUserDetails(String token){
        Claims body = jwtUtil.parseJwtToken(token);
        String uuid = (String) body.get("uuid");
        log.info("uuid: {}", uuid);
        String key = RedisBucketConstant.LOGIN_TOKEN_BUCKET + uuid;
        return redisCache.getCacheObject(key);
    }

    public boolean removeUserToken(String token){
        Claims body = Jwts.parser().parseClaimsJws(token).getBody();
        String uuid = (String) body.get("uuid");
        return redisCache.deleteObject(RedisBucketConstant.LOGIN_TOKEN_BUCKET + uuid);
    }

    public boolean refreshUserToken(String token){
        Claims body = Jwts.parser().parseClaimsJws(token).getBody();
        String uuid = (String) body.get("uuid");
        return redisCache.expire(RedisBucketConstant.LOGIN_TOKEN_BUCKET + uuid, 30, TimeUnit.MINUTES);
    }

    public UserDetails getUserDetailsByHeader(HttpServletRequest request){
        String authorization = request.getHeader("Authorization");
        String token = null;
        if (authorization != null && authorization.startsWith("Bearer ")) {
            token = authorization.substring(7);
        } else {
            throw new LoginExpiredException("token is null");
        }
        return getUserDetails(token);
    }
}